/**
 * ZipUtils.java
 * com.ebook.util
 * Copyright (c) 2013, 公司版权所有.
*/

package com.ebook.util;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;

import org.apache.commons.compress.archivers.ArchiveException;
import org.apache.commons.compress.archivers.ArchiveStreamFactory;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.compress.utils.IOUtils;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * @author    潘吉友
 * @Date	 2013-5-20 	 
 */
public class ZipUtils {   
	
	private static Log logger = LogFactory.getLog(ZipUtils.class); 
	
	public static final String EXT = ".zip";   
    private static final String BASE_DIR = "";   
    private static final String PATH = "/";   
    private static final int BUFFER = 1024;   
    
    public static void deCompressZip(String zipPath,String deCompressPath) throws IOException, ArchiveException{
    	ZipFile file =new ZipFile(zipPath,"gbk");
    	Enumeration<ZipArchiveEntry> en =file.getEntries();
    	ZipArchiveEntry ze;
    	while(en.hasMoreElements()){
    		ze =en.nextElement();
    		File f =new File(deCompressPath,ze.getName());
    		System.out.println(ze.getName());
    		if(ze.isDirectory()){    
    			f.mkdirs();
    			continue;
    		}else{
    			f.getParentFile().mkdirs();   
    		}
    		InputStream is =file.getInputStream(ze);
    		OutputStream os =new FileOutputStream(f);
    		IOUtils.copy(is, os, BUFFER);
    		is.close();
    		os.close();
    	}
    	file.close();
    }
    
    /**
     * 解压zip文件内包含同名文件夹时，去除同名文件夹
     * 例如：tt.zip内有/tt/*,解压后为/*
     * @param zipPath
     * @param deCompressPath
     * @throws IOException
     * @throws ArchiveException 
    */
    public static void deCompressZip1(String zipPath,String deCompressPath) throws IOException, ArchiveException{
    	ZipFile file =new ZipFile(zipPath,"gbk");
    	Enumeration<ZipArchiveEntry> en =file.getEntries();
    	ZipArchiveEntry ze ;
    	while(en.hasMoreElements()){
    		ze =en.nextElement();
    		String zipName = zipPath.substring(zipPath.lastIndexOf("/")+1, zipPath.lastIndexOf(".zip"));
    		String zeName = ze.getName().substring(0,ze.getName().length()-1);
    		if(zipName.equals(zeName)){
    			continue;
    		}
    		String zePath = ze.getName().substring(ze.getName().indexOf("/")+1);
    		File f =new File(deCompressPath,zePath);
    		System.out.println(zePath);
    		if(ze.isDirectory()){    
    			f.mkdirs();
    			continue;
    		}else{
    			f.getParentFile().mkdirs();   
    		}
    		InputStream is =file.getInputStream(ze);
    		OutputStream os =new FileOutputStream(f);
    		IOUtils.copy(is, os, BUFFER);
    		is.close();
    		os.close();
    	}
    	file.close();
    }
    
    

    
    public static void main(String[] args) throws Exception {
    	
    	long start = System.currentTimeMillis();
    	ZipUtils.deCompressZip1("C:/Users/TechKno001/Desktop/6_java思想.zip", "C:/Users/TechKno001/Desktop/tt/bb");
    	
//    	ZipUtils.compress("C:\\Users\\TechKno001\\Desktop\\tt\\aa","C:\\Users\\TechKno001\\Desktop\\aa.zip");  
//    	ZipUtils.compress("C:\\Users\\TechKno001\\Desktop\\tt\\aa","C:\\Users\\TechKno001\\Desktop\\aa.zip");  
    	long end = System.currentTimeMillis();
		System.out.println(start);
		System.out.println(end);
		System.out.println("解压用时："+(end-start)+"ms");
	}
	  
     
    
   
    /**  
     * 压缩  
     *   
     * @param srcFile  
     * @throws Exception  
     */
    public static void compress(File srcFile) throws Exception {   
        String name = srcFile.getName();   
        String basePath = srcFile.getParent();   
        String destPath = basePath + name + EXT;   
        compress(srcFile, destPath);   
    }   
  
    /**  
     * 压缩  
     *   
     * @param srcFile  
     *            源路径  
     * @param destPath  
     *            目标路径  
     * @throws Exception  
     */ 
    public static void compress(File srcFile, File destFile) throws Exception {   
  
    	ZipArchiveOutputStream zos =(ZipArchiveOutputStream) new ArchiveStreamFactory()
		.createArchiveOutputStream("zip", new FileOutputStream(destFile)); //or new ZipArchiveOutputStream(new FileOutputStream(path)) 
	zos.setEncoding("gbk");
	if(srcFile.isDirectory()){
		File[] files = srcFile.listFiles();
		for(File f : files){
			 compress(f, zos, BASE_DIR); 
		}
	}else{
		 compress(srcFile, zos, BASE_DIR); 
	}
	
        zos.flush();   
        zos.close();   
    }   
  
    /**  
     * 压缩文件  
     *   
     * @param srcFile  
     * @param destPath  
     * @throws Exception  
     */  
    public static void compress(File srcFile, String destPath) throws Exception {   
        compress(srcFile, new File(destPath));   
    }   
  
    
  
    /**  
     * 压缩  
     *   
     * @param srcPath  
     * @throws Exception  
     */  
    public static void compress(String srcPath) throws Exception {   
        File srcFile = new File(srcPath);   
        compress(srcFile);   
    }   
  
    /**  
     * 文件压缩  
     *   
     * @param srcPath  
     *            源文件路径  
     * @param destPath  
     *            目标文件路径  
     *   
     */
    public static void compress(String srcPath, String destPath)   
            throws Exception { 
    	logger.info("compress_srcPath: "+srcPath);
    	logger.info("compress_destPath: "+destPath);
        File srcFile = new File(srcPath);   
  
        compress(srcFile, destPath);   
    }  
    
    /**  
     * 压缩  
     *   
     * @param srcFile  
     *            源路径  
     * @param zos  
     *            ZipOutputStream  
     * @param basePath  
     *            压缩包内相对路径  
     * @throws Exception  
     */  
    private static void compress(File srcFile, ZipArchiveOutputStream zos,   
            String basePath) throws Exception {   
        if (srcFile.isDirectory()) {   
            compressDir(srcFile, zos, basePath);   
        } else {   
            compressFile(srcFile, zos, basePath);   
        }   
    }   
    
  
    /**  
     * 压缩目录  
     *   
     * @param dir  
     * @param zos  
     * @param basePath  
     * @throws Exception  
     */  
    private static void compressDir(File dir, ZipArchiveOutputStream zos,   
            String basePath) throws Exception {   
  
        File[] files = dir.listFiles();   
  
        // 构建空目录   
        if (files.length < 1) {   
        	ZipArchiveEntry entry = new ZipArchiveEntry(basePath + dir.getName() + PATH);   
            System.out.println(basePath + dir.getName() + PATH);
  
            zos.putArchiveEntry(entry);   
            zos.closeArchiveEntry();   
        }   
        for (File file : files) {   
            // 递归压缩   
            compress(file, zos, basePath + dir.getName() + PATH);   
  
        }   
    }   
  
    /**  
     * 文件压缩  
     *   
     * @param file  
     *            待压缩文件  
     * @param zos  
     *            ZipOutputStream  
     * @param dir  
     *            压缩文件中的当前路径  
     * @throws Exception  
     */
    private static void compressFile(File file, ZipArchiveOutputStream zos, String dir)   
            throws Exception {   
  
        ZipArchiveEntry entry = new ZipArchiveEntry(dir + file.getName());   
        zos.putArchiveEntry(entry);   
        System.out.println(dir + file.getName());
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(   
                file));   
  
        int count;   
        byte data[] = new byte[BUFFER];   
        while ((count = bis.read(data, 0, BUFFER)) != -1) {   
            zos.write(data, 0, count);   
        }   
        bis.close();   
  
        zos.closeArchiveEntry();   
    }   
  

}  


